﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.ServiceModel.DomainServices.Client;
using TelecoSystems.Web.Services.Contracts;
using TelecoSystems.Infrastructure.Views;
using TelecoSystems.Infrastructure.Helpers;
using TelecoSystems.Web.Models.PresentationModel;
using Microsoft.Practices.Composite.Presentation.Commands;
using System.ComponentModel;
using TelecoSystems.Web;

namespace TelecoSystems.Modules.Contracts.ViewModels
{
    public class ContractsBrowseViewModel : PagedViewModelBase
    {
        #region Fields
        private ContractsDomainContext _contractsCtx;
        private AuthenticationContext _authCtx;
        #endregion

        #region Constructors
        public ContractsBrowseViewModel(ContractsDomainContext contractsCtx) {
            _contractsCtx = contractsCtx;
            _authCtx = new AuthenticationContext();

            Contracts = new PagedEntityCollectionView<ContractPM>(_contractsCtx.ContractPMs, this);

            SubmitChangesCommand = new DelegateCommand<object>(SubmitChanges, CanSubmitChanges);
            CancelCommand = new DelegateCommand<object>(Cancel, o => true);
            AddContractCommand = new DelegateCommand<object>(AddContract, CanAddContract);
            DeleteContractCommand = new DelegateCommand<object>(DeleteContract, CanDeleteContract);

            LoadData();
        } 
        #endregion

        #region Data
        public override void LoadData() {
            if (IsLoading || _contractsCtx == null) {
                return;
            }

            IsBusy = true;
            IsLoading = true;

            _contractsCtx.ContractPMs.Clear();
            var q = _contractsCtx.GetContractsQuery();            
            /*if (Contracts.SortDescriptions.Count > 0) {
                bool isFirst = true;
                foreach (SortDescription sd in Products.SortDescriptions) {
                    q = OrderBy(q, isFirst, sd.PropertyName, sd.Direction == ListSortDirection.Descending);
                    isFirst = false;
                }
            } else {
                q = q.OrderBy(p => p.Id);
            }

            if (PageSize > 0) {
                q = q.Skip(PageSize * PageIndex);
                q = q.Take(PageSize);
            }*/

            _contractsCtx.Load(q, ContractsLoaded, null);
        }

        private bool _isBusy = false;
        public bool IsBusy {
            get { return _isBusy; }
            set {
                if (_isBusy != value) {
                    _isBusy = value;
                    NotifyPropertyChanged("IsBusy");
                }
            }
        }

        private string _busyContent = "Please wait...";
        public string BusyContent {
            get { return _busyContent; }
            set {
                if (_busyContent != value) {
                    _busyContent = value;
                    NotifyPropertyChanged("BusyContent");
                }
            }
        }
        #endregion 

        #region VM Properties
        private PagedEntityCollectionView<ContractPM> _contracts;
        public PagedEntityCollectionView<ContractPM> Contracts {
            get { return _contracts; }
            set {
                if (_contracts != value) {
                    _contracts = value;
                    NotifyPropertyChanged("Contracts");
                }
            }
        }

        private ContractPM _contractDetail;
        public ContractPM ContractDetail {
            get { return _contractDetail; }
            set { 
                if (_contractDetail != value) {
                    _contractDetail = value;                    
                    NotifyPropertyChanged("ContractDetail");

                    _contractDetail.PropertyChanged += (s, e) => {
                        if (SubmitChangesCommand != null)
                            SubmitChangesCommand.RaiseCanExecuteChanged();
                    };
                }
            }
        }

        public string HeaderInfo { get { return "Browse Contracts"; } } 
        #endregion

        public event EventHandler ContractAdded;
        protected virtual void OnContractAdded(EventArgs e) {
            if (ContractAdded != null) {
                ContractAdded(this, e);
            }
        }

        #region Commands
        public DelegateCommand<object> SubmitChangesCommand { get; set; }
        void SubmitChanges(object o) {
            IsBusy = true;
            _contractsCtx.SubmitChanges(SubmitChangesCompleted, null);
        }
        bool CanSubmitChanges(object o) {
            return _contractsCtx.HasChanges || ((ContractDetail != null) ? ContractDetail.HasChanges : false);
        }

        public DelegateCommand<object> CancelCommand { get; set; }
        void Cancel(object o) {
            if (ContractDetail.HasChanges) {
                ((IRevertibleChangeTracking)ContractDetail).RejectChanges();
            }
        }

        public DelegateCommand<object> AddContractCommand { get; set; }
        void AddContract(object o) {
            ContractDetail = new ContractPM();
            _contractsCtx.ContractPMs.Add(ContractDetail);
            OnContractAdded(null);
            //NotifyPropertyChanged("ContractDetail");
            //NotifyPropertyChanged("Contracts");
        }
        bool CanAddContract(object o) {
            return _contractsCtx != null;
        }

        public DelegateCommand<object> DeleteContractCommand { get; set; }
        void DeleteContract(object o) {
            Contracts.Remove(ContractDetail);
        }
        bool CanDeleteContract(object o) {
            return ContractDetail != null;
        }
        #endregion

        #region Event Handlers
        private void ContractsLoaded(LoadOperation<ContractPM> loadOperation) {
            if (loadOperation.HasError) {
                ErrorWindow.CreateNew(loadOperation.Error, StackTracePolicy.OnlyWhenDebuggingOrRunningLocally);
            } else {
                Contracts.MoveCurrentToFirst();

                ItemCount = loadOperation.TotalEntityCount;
                TotalItemCount = loadOperation.TotalEntityCount;
                InformationWindow.Create("Contracts were loaded successfully.", "Notification");
            }
            IsLoading = false;
            IsBusy = false;
        }

        private void SubmitChangesCompleted(SubmitOperation submit) {
            if (submit.HasError) {
                foreach (Entity entity in submit.EntitiesInError) {

                }
                ErrorWindow.CreateNew(submit.Error, StackTracePolicy.OnlyWhenDebuggingOrRunningLocally);
            } else {
                InformationWindow.Create("Changes were saved successfully.", "Information");
            }
            IsBusy = false;
        }
        #endregion
    }
}
